compio_driver\sys\driver\iocp/op.rs
1use super::*;
2/// Abstraction of IOCP operations.
3///
4/// # Safety
5///
6/// Implementors must ensure that the operation is safe to be polled
7/// according to the returned [`OpType`].
8pub unsafe trait OpCode {
9 /// Type that contains self-references and other needed info during the
10 /// operation
11 type Control: Default;
12
13 /// Initialize the control
14 ///
15 /// # Safety
16 ///
17 /// Caller must guarantee that during the lifetime of `ctrl`, `Self` is
18 /// unmoved and valid.
19 unsafe fn init(&mut self, _: &mut Self::Control) {}
20
21 /// Determines that the operation is really overlapped defined by
22 /// Windows API. If not, the driver will try to operate it in
23 /// another thread.
24 fn op_type(&self, control: &Self::Control) -> OpType {
25 _ = control;
26 OpType::Overlapped
27 }
28
29 /// Perform Windows API call with given pointer to overlapped struct.
30 ///
31 /// It is always safe to cast `optr` to a pointer to
32 /// [`Overlapped<Self>`].
33 ///
34 /// Don't do heavy work here if [`OpCode::op_type`] returns
35 /// [`OpType::Event`].
36 ///
37 /// # Safety
38 ///
39 /// * `self` must be alive until the operation completes.
40 /// * When [`OpCode::op_type`] returns [`OpType::Blocking`], this method is
41 /// called in another thread.
42 unsafe fn operate(
43 &mut self,
44 control: &mut Self::Control,
45 optr: *mut OVERLAPPED,
46 ) -> Poll<io::Result<usize>>;
47
48 /// Cancel the async IO operation.
49 ///
50 /// Usually it calls `CancelIoEx`.
51 // # Safety for implementors
52 //
53 // `optr` must not be dereferenced. It's only used as a marker to identify the
54 // operation.
55 fn cancel(&mut self, control: &mut Self::Control, optr: *mut OVERLAPPED) -> io::Result<()> {
56 _ = control;
57 _ = optr;
58 Ok(())
59 }
60
61 /// Set the result when it completes.
62 /// The operation stores the result and is responsible to release it if
63 /// the operation is cancelled.
64 ///
65 /// # Safety
66 ///
67 /// The params must be the result coming from this operation.
68 unsafe fn set_result(
69 &mut self,
70 _: &mut Self::Control,
71 _: &io::Result<usize>,
72 _: &crate::Extra,
73 ) {
74 }
75}
76
77pub(crate) trait Carry {
78 fn op_type(&self) -> OpType;
79
80 unsafe fn operate(&mut self, optr: *mut OVERLAPPED) -> Poll<io::Result<usize>>;
81
82 fn cancel(&mut self, optr: *mut OVERLAPPED) -> io::Result<()>;
83
84 unsafe fn set_result(&mut self, _: &io::Result<usize>, _: &crate::Extra);
85}
86
87impl<T: OpCode> Carry for Carrier<T> {
88 fn op_type(&self) -> OpType {
89 let (op, control) = self.as_iocp();
90 op.op_type(control)
91 }
92
93 unsafe fn operate(&mut self, optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
94 let (op, control) = self.as_iocp_mut();
95 unsafe { op.operate(control, optr) }
96 }
97
98 fn cancel(&mut self, optr: *mut OVERLAPPED) -> io::Result<()> {
99 let (op, control) = self.as_iocp_mut();
100 op.cancel(control, optr)
101 }
102
103 unsafe fn set_result(&mut self, res: &io::Result<usize>, extra: &crate::Extra) {
104 let (op, control) = self.as_iocp_mut();
105 unsafe { op.set_result(control, res, extra) }
106 }
107}